package gbench.sandbox.plot;

import gbench.common.fs.FileSystem;
import gbench.common.matlib.MatlibCanvas;
import gbench.common.matlib.MatlibCanvas.NVec;
import gbench.common.matlib.MatlibCanvas.Seq;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static gbench.common.matlib.MatlibCanvas.Range.P2;
import static gbench.common.matlib.img.ImageOps.img2rgbinfo;
import static gbench.common.matlib.img.ImageOps.rgbinfo2xyrgbS;
import static java.lang.Math.PI;

/**
 * 
 * 绘制五星（含有读取读片并显示读片的功能）
 * @author gbench
 *
 */
public class JunitPlotStar {
    /**
     * 绘制五星（含有读取读片并显示读片的功能）
     * 
     * @throws InterruptedException
     */
    @Test
    public void plot_star() throws InterruptedException {
        final var size = 1000;// 绘图范围
        final var matlib = new MatlibCanvas(size); // 绘图画板
        final var len = 100; // 五角星的角顶点的向量的长度
        final var n = 5 * 2; // 角度单元数
        final var ar = new AtomicInteger(len); // 向量的矢量径长
        final var star_points = P2(-PI, PI, n + 1) // 绘制一个圆周，注意 n+1个点定义n个区间,端点（角顶点）位于区间的中心
                .map(theta -> matlib.rhoTheta(theta - PI / n)) // 回转一个半角的角度(2PI/2n,PI/n),使得星星姿态端正，为何是半个角度，看一下下图的内接10边形就明白了。
                .map(e -> e.affine(ar.get(), ar.getAndUpdate(x -> x == len ? (len / 3) : len), size / 2, size / 4)) // 构造 len,len/3,len,len/3,...的长短间隔的矢径序列
                .collect(Collectors.toList()); // 五角星的端点的集合
        final var rgbinfo = img2rgbinfo(FileSystem.path("data/bg_pattern.jpg", this.getClass())); // 背景图纹
        final var hh = rgbinfo.filter("width,height").mutate(rec -> rec.toArray(Integer.class));// width,height 数组
        matlib.plot(size, size / 2, pen -> { // 绘制五角星
            rgbinfo2xyrgbS(rgbinfo, NVec::new).peek(e -> e.idval_mul(0, size * 1d / hh[0], 1, size / 2 * 1d / hh[1])).forEach(pen::drawPoint); // 背景图纹
            pen.setColor("#ffff00"); // 设置画笔颜色 黄色
            Seq.sliding(star_points, 2, 1).stream().filter(e -> e.length > 1).forEach(pen::drawStraightLine); // 把五角星的端点连起来
            P2(-PI, PI, 1000).map(matlib.rhotheta_affine(len, len, size / 2, size / 4)).forEach(pen::drawPoint); // 外部的轮廓圆圈
        }, null, true, null, ArrayList::new); // 绘制五角星

        Thread.sleep(100000);// 图片显示时间:10 S 
    }
    
    /**
     * 绘制 10边形（含有读取读片并显示读片的功能）的 思想起点：内接 10边形
     * 
     * @throws InterruptedException
     */
    @Test
    public void inscribed_polygon() throws InterruptedException {
        final var size = 1000;// 绘图范围
        final var matlib = new MatlibCanvas(size); // 绘图画板
        final var len = 100; //  10边形的角顶点的向量的长度
        final var n = 5 * 2; // 角度单元数：边数
        final var ar = new AtomicInteger(len); // 向量的矢量径长
        final var star_points = P2(-PI, PI, n + 1) // 绘制一个圆周，注意 n+1个点定义n个区间,端点（角顶点）位于区间的中心
                .map(theta -> matlib.rhoTheta(theta - 0)) // 不做角度回转
                .map(e -> e.affine(ar.get(), ar.getAndUpdate(x -> x == len ? (len / 1) : len), size / 2, size / 4)) // 构造 len,len/1,len,len/1,...的间隔的矢径序列
                .collect(Collectors.toList()); //  10边形的端点的集合
        final var rgbinfo = img2rgbinfo(FileSystem.path("data/bg_pattern.jpg", this.getClass())); // 背景图纹
        final var hh = rgbinfo.filter("width,height").mutate(rec -> rec.toArray(Integer.class));// width,height 数组
        matlib.plot(size, size / 2, pen -> { // 绘制 10边形
            rgbinfo2xyrgbS(rgbinfo, NVec::new).peek(e -> e.idval_mul(0, size * 1d / hh[0], 1, size / 2 * 1d / hh[1])).forEach(pen::drawPoint); // 背景图纹
            pen.setColor("#ffff00"); // 设置画笔颜色 黄色
            Seq.sliding(star_points, 2, 1).stream().filter(e -> e.length > 1).forEach(pen::drawStraightLine); // 把 10边形的端点连起来
            P2(-PI, PI, 1000).map(matlib.rhotheta_affine(len, len, size / 2, size / 4)).forEach(pen::drawPoint); // 外部的轮廓圆圈
        }, null, true, null, ArrayList::new); // 绘制 10边形

        Thread.sleep(100000);// 图片显示时间:10 S 
    }
}
